/*
 * ﻿Copyright (C) 2012-2013 NewMain Softech
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package com.newmainsoftech.ant.types;

import java.lang.reflect.Method;
import java.util.Arrays;

import org.apache.tools.ant.types.Commandline.Argument;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.newmainsoftech.ant.types.ArgumentContract.MethodSetPartsField;

@Aspect
public class ArgumentExtAspect {
	Logger logger = LoggerFactory.getLogger( this.getClass());
		protected Logger getLogger() {
			return logger;
		}
	
	@Pointcut( value="execution( public * com.newmainsoftech.ant.types.ArgumentContract.*(..)) " 
				+ "&& within( com.newmainsoftech.ant.types.ArgumentExt) && if()")
	public static boolean pointcutAtExecutionOfArgumentContractMethods( JoinPoint joinPoint) {
		MethodSignature methodSignature = (MethodSignature)(joinPoint.getSignature());
		Method method = methodSignature.getMethod();
		String methodName = method.getName();
		Class<?>[] argTypeArray = method.getParameterTypes();
		for( MethodSetPartsField methodSetPartsField : MethodSetPartsField.values()) {
			if ( !methodName.equals( methodSetPartsField.getArgumentContractMethod().getName())) continue; // for
			if ( !Arrays.equals(
					argTypeArray, methodSetPartsField.getArgumentContractMethod().getParameterTypes())
				) 
			{
				continue; // for
			}
			return true;
		} // for
		return false;
	}
		@AfterReturning( pointcut="pointcutAtExecutionOfArgumentContractMethods( joinPoint)")
		public void afterReturningAdvisedExecutionOfArgumentContractMethods( JoinPoint joinPoint) {
			Logger logger = getLogger();
				if ( logger.isDebugEnabled()) {
					MethodSignature methodSignature = (MethodSignature)(joinPoint.getSignature());
					logger.debug(
							String.format(
									"Entering %1$s method of %2$s.",
									methodSignature.getMethod().getName(), 
									joinPoint.getTarget().toString()
									)
							);
					logger.debug( 
							String.format(
									"Thead ID: %1$d%nStack-trace to here: %n%2$s",
									Thread.currentThread().getId(),
									Arrays.toString( Arrays.copyOf( Thread.currentThread().getStackTrace(), 7))
									)
							);
				}
				
			
			ArgumentExt argumentExt = (ArgumentExt)(joinPoint.getTarget());
			argumentExt.setArgList( null);
				if ( logger.isDebugEnabled()) {
					Object targetObj = joinPoint.getTarget();
					logger.debug( 
							String.format(
									"Nullified argList member field of %1$s.",
									targetObj.toString()
									)
							);
					
					MethodSignature methodSignature = (MethodSignature)(joinPoint.getSignature());
					logger.debug(
							String.format(
									"Exited %1$s method of %2$s",
									methodSignature.getMethod().getName(), 
									targetObj.toString()
									)
							);
				}
		}
}
